using System;
using System.Collections.Generic;
using System.Text;

namespace CardSystemUtils
{
    public class Generator
    {
        public static byte[] CreateLuhnNumber(int length)
        {
            Random rnd = new Random();
            byte[] digits = new byte[length];

            for (int i = 0; i < length - 1; i++)
            {
                digits[i] = (byte)rnd.Next(10);
            }

            int sum = 0;
            bool alt = true;
            for (int i = length - 2; i >= 0; i--)
            {
                if (alt)
                {
                    int temp = digits[i];
                    temp *= 2;
                    if (temp > 9) temp -= 9;
                    sum += temp;
                }
                else sum += digits[i];
                alt = !alt;
            }

            int modulo = sum % 10;
            if (modulo > 0) digits[length - 1] = (byte)(10 - modulo);

            return digits;
        }

        static byte[] CreateMasterCardNo()
        {
            const int length = 16;
            Random rnd = new Random();

            byte[] digits = new byte[length];
            digits[0] = 5;
            digits[1] = (byte)rnd.Next(1, 6);

            for (int i = 2; i < length - 1; i++)
            {
                digits[i] = (byte)rnd.Next(10);
            }

            int sum = 0;
            bool alt = true;
            for (int i = length - 2; i >= 0; i--)
            {
                if (alt)
                {
                    int temp = digits[i];
                    temp *= 2;
                    if (temp > 9) temp -= 9;
                    sum += temp;
                }
                else sum += digits[i];
                alt = !alt;
            }

            int modulo = sum % 10;
            if (modulo > 0) digits[length - 1] = (byte)(10 - modulo);

            return digits;
        }

        static byte[] CreateVisaCardNo()
        {
            byte[] lengths = { 13, 16 };
            Random rnd = new Random();
            int length = lengths[rnd.Next(2)];

            byte[] digits = new byte[length];
            digits[0] = 4;

            for (int i = 2; i < length - 1; i++)
            {
                digits[i] = (byte)rnd.Next(10);
            }

            int sum = 0;
            bool alt = true;
            for (int i = length - 2; i >= 0; i--)
            {
                if (alt)
                {
                    int temp = digits[i];
                    temp *= 2;
                    if (temp > 9) temp -= 9;
                    sum += temp;
                }
                else sum += digits[i];
                alt = !alt;
            }

            int modulo = sum % 10;
            if (modulo > 0) digits[length - 1] = (byte)(10 - modulo);

            return digits;
        }

        public static byte[] CreateCardNo(CardType type)
        {
            byte[] digits = null;

            switch (type)
            {
                case CardType.Master:
                    digits = CreateMasterCardNo();
                    break;
                case CardType.Visa:
                    digits = CreateVisaCardNo();
                    break;
                default:
                    break;
            }

            return digits;
        }
    }
}
